package fractales.algo;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.util.Date;
import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class Mandelbrot extends JPanel
{
	private BufferedImage image;
	private Thread t;
	private boolean stop;
	
	public void paintComponent(final Graphics g1)
	{
		if (image == null)
		{
			if (t != null)
			{
				stop = true;
				while (t.isAlive())
					;
				try
				{
					t.join();
				}
				catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				stop = false;
			}
			
			image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
			final Timer timer = new Timer();
			
			t = new Thread()
			{
				
				@Override
				public void run()
				{
					
					try
					{
						sleep(500);
					}
					catch (InterruptedException e1)
					{
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					double width = Mandelbrot.this.getWidth();
					double height = Mandelbrot.this.getHeight();
					
					int m, n;
					double p, q, x, y, u, v;
					int i;
					
					for (n = 0; n < height; n++)
					{
						for (m = 0; m < width; m++)
						{
							if (stop)
								return;
							
							p = (m - width / 2. -1500) / 7000.;
							q = (n - height / 2. +5000.) / 7000.;
							x = 0;
							y = 0;
							for (i = 0; i < 0xff; i++)
							{
								u = x * x - y * y + p;
								v = 2 * x * y + q;
								if (u * u + v * v > 4)
								{
									break;
								}
								x = u;
								y = v;
							}
							int rgb = (i << 16) | (i * 5 << 8) | i * 12;
							image.setRGB(m, n, rgb);
						}
					}
					timer.cancel();
					repaint();
				}
			};
			
			t.start();
			
			TimerTask ttask = new TimerTask()
			{
				@Override
				public void run()
				{
					repaint();
				}
			};
			
			timer.scheduleAtFixedRate(ttask, 500, 500);
		}
		
		g1.drawImage(image, 0, 0, Mandelbrot.this);
	}
	
	public static void main(String[] args)
	{
		try
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch (Exception e)
		{
		}
		
		final JFrame f = new JFrame();
		
		JPanel p = new Mandelbrot();
		Mandelbrot mdlbrt = new Mandelbrot();
		f.add(mdlbrt);
		
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setLayout(new BorderLayout());
		f.setMinimumSize(new Dimension(1024, 768));
		f.add(p);
		
		f.setVisible(true);
		// mdlbrt.repaint();
	}
}
